package bg.code.commons.plugin.ui.table;

import bg.code.commons.builder.dto.ResultDTO;
import bg.code.commons.builder.utils.Strings;
import bg.code.commons.builder.vo.ColumnDescriptor;
import bg.code.commons.plugin.ui.model.FieldTableModel;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.panels.VerticalBox;
import com.intellij.ui.table.JBTable;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import java.util.ArrayList;
import java.util.List;

import static bg.code.commons.plugin.Cons.FIELD_ANNOTATION_INFO;

/**
 * @author 郑兴泉 956607644@qq.com
 * @data 2020/8/11
 * 描述：
 */
public final class FieldJBPanel implements ICustomJBPanel<JBTable> {

    private final JBTable table;
    private final List<ColumnDescriptor> javaFields;

    public FieldJBPanel(List<ColumnDescriptor> javaFields) {
        this.javaFields = javaFields;
        this.table = new JBTable();
    }

    @Override
    public JComponent getComponent() {
        VerticalBox root = new VerticalBox();
        this.table.setShowGrid(true);
        this.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        this.table.setModel(new FieldTableModel(javaFields));
        this.table.setRowHeight(30);
        changeCellWith();
        addTableModelListener();
        JScrollPane pane = new JBScrollPane(this.table);
        pane.setBorder(BorderFactory.createTitledBorder(FIELD_ANNOTATION_INFO));
        root.add(pane);
        return root;
    }

    @Override
    public List<ColumnDescriptor> getData() {
        List<ColumnDescriptor> methodDescriptors = new ArrayList<>(10);
        TableModel model = this.table.getModel();
        int rowLen = model.getRowCount(), cellLen = model.getColumnCount();
        for (int row = 0; row < rowLen; row++) {
            ColumnDescriptor descriptor = new ColumnDescriptor();
            descriptor.setName(Strings.sNull(model.getValueAt(row, 1)));
            descriptor.setPrimaryKey(Strings.sBoolean(model.getValueAt(row, 2)));
            descriptor.setComment(Strings.sNull(model.getValueAt(row, 3)));
            descriptor.setColumnName(Strings.sNull(model.getValueAt(row, 4)));
            descriptor.setType(Strings.sNull(model.getValueAt(row, 5)));
            descriptor.setFullType(Strings.sNull(model.getValueAt(row, 6)));
            descriptor.setDate(Strings.sBoolean(model.getValueAt(row, 7)));
            descriptor.setDateFormat(Strings.sNull(model.getValueAt(row, 8)));
            descriptor.setDict(Strings.sBoolean(model.getValueAt(row, 9)));
            descriptor.setDictCode(Strings.sNull(model.getValueAt(row, 10)));
            descriptor.setMultiDict(Strings.sBoolean(model.getValueAt(row, 11)));
            descriptor.setRequired(Strings.sBoolean(model.getValueAt(row, 12)));
            descriptor.setQueryState(Strings.sBoolean(model.getValueAt(row, 13)));
            descriptor.setSingleInput(Strings.sBoolean(model.getValueAt(row, 14)));
            descriptor.setSingleSelect(Strings.sBoolean(model.getValueAt(row, 15)));
            descriptor.setMultipleSelect(Strings.sBoolean(model.getValueAt(row, 16)));
            descriptor.setMultipleInput(Strings.sBoolean(model.getValueAt(row, 17)));
            descriptor.setMultipleInputWidth(Strings.sInt(model.getValueAt(row, 18)));
            descriptor.setMultipleInputHeight(Strings.sInt(model.getValueAt(row, 19)));
            descriptor.setBaiDuUe4(Strings.sBoolean(model.getValueAt(row, 19)));
            descriptor.setShow(Strings.sBoolean(model.getValueAt(row, 19)));
            descriptor.setShowLabelName(Strings.sNull(model.getValueAt(row, 19)));
            descriptor.setShowPlaceholder(Strings.sNull(model.getValueAt(row, 19)));
            descriptor.setAttachment(Strings.sBoolean(model.getValueAt(row, 19)));
            descriptor.setAttachmentMultiple(Strings.sBoolean(model.getValueAt(row, 19)));
            descriptor.setAttachmentAllIsImg(Strings.sBoolean(model.getValueAt(row, 19)));
            descriptor.setAttachSuffix(Strings.sNull(model.getValueAt(row, 19)));
            descriptor.setPlaceholder(Strings.sNull(model.getValueAt(row, 19)));
            descriptor.setLabelName(Strings.sNull(model.getValueAt(row, 19)));
            descriptor.setMaxLength(Strings.sInt(model.getValueAt(row, 19)));
            descriptor.setOneOne(Strings.sBoolean(model.getValueAt(row, 19)));
            descriptor.setOneOneField(Strings.sNull(model.getValueAt(row, 19)));
            descriptor.setOneOneClassName(Strings.sNull(model.getValueAt(row, 19)));
            descriptor.setOneOneClassQualifiedName(Strings.sNull(model.getValueAt(row, 19)));
            methodDescriptors.add(descriptor);

        }
        return methodDescriptors;
    }

    @Override
    public JBTable getObj() {
        return table;
    }


    private void addTableModelListener() {
        // 在 表格模型上 添加 数据改变监听器
        TableModel model = this.table.getModel();
        model.addTableModelListener(new MethodParamTableModelListener(model));
    }

    static class MethodParamTableModelListener implements TableModelListener {

        private final TableModel tableModel;

        public MethodParamTableModelListener(TableModel tableModel) {
            this.tableModel = tableModel;
        }

        @Override
        public void tableChanged(TableModelEvent e) {
            // 获取 第一个 和 最后一个 被改变的行（只改变了一行，则两者相同）
            int firstRow = e.getFirstRow();
            int lastRow = e.getLastRow();
            int type = e.getType();
            int column = e.getColumn();
            // 事件的类型，可能的值有:
            //     TableModelEvent.INSERT   新行或新列的添加
            //     TableModelEvent.UPDATE   现有数据的更改
            //     TableModelEvent.DELETE   有行或列被移除
            if (type == TableModelEvent.UPDATE || type == TableModelEvent.INSERT) {
                if (column < 4 || column > 4) {
                    return;
                }
                for (int row = firstRow; row <= lastRow; row++) {
                    Object methodRequestPath = tableModel.getValueAt(row, 4);
                    // 全请求路径名称
                    tableModel.setValueAt(methodRequestPath + "/" + methodRequestPath, row, 5);
                    // 权限标识名称
                    tableModel.setValueAt(methodRequestPath + ":" + methodRequestPath, row, 6);
                }
            }
        }
    }

    public void changeCellWith() {
        TableModel fieldsModel = this.table.getModel();
        int headersLength = fieldsModel.getColumnCount();
        TableColumnModel columnModel = this.table.getColumnModel();
        for (int i = 0; i < headersLength; ++i) {
            TableColumn tableColumn = columnModel.getColumn(i);
            Object value = fieldsModel.getValueAt(0, i);
            if (value instanceof Boolean) {
                // 列宽
                tableColumn.setPreferredWidth(100);
            } else if (value instanceof Integer) {
                tableColumn.setPreferredWidth(50);
            } else {
                tableColumn.setPreferredWidth(150);
            }
        }
    }

    @Override
    public ResultDTO errorMsg() {
        return null;
    }
}
